package org.paul.withconfig.vm

import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.*
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.delay
import org.paul.ConfigAdapter
import org.paul.R
import org.paul.noconfig.vm.ConstraintSetExt
import java.util.*

class WithConfigViewModelActivity : AppCompatActivity() {
    private val viewModel: NoConfigViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_config_viewmodel)
        val content = findViewById<AppCompatTextView>(R.id.content)
        viewModel.data.observe(this, Observer {
            content.text = getString(R.string.time_fmt, it)
        })
        val adapter = ConfigAdapter()
        findViewById<RecyclerView>(R.id.recycler).apply {
            this.adapter = adapter
        }
        viewModel.generateList.observe(this, Observer {
            adapter.submitList(it)
        })

        constraintSetExt = intent.extras?.get("config") as ConstraintSetExt
    }

    lateinit var constraintSetExt: ConstraintSetExt

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        if (newConfig.orientation != orientation) {
            // means config changed
            Log.d(tag, "WithConfigViewModelActivity config changed and now it is ${newConfig.orientation}")
            // load local contrainset

            if (newConfig.orientation == ORIENTATION_LANDSCAPE){
                val set = ConstraintSet().apply {
                    clone(this@WithConfigViewModelActivity, R.id.container)
                }
                constraintSetExt.set.applyTo(findViewById(R.id.container))
            }

            // save new orientation
            orientation = newConfig.orientation
        }
    }

    private val tag = "configChange"
    var orientation: Int = ORIENTATION_PORTRAIT
}

class NoConfigViewModel : ViewModel() {

    private val _data: LiveData<String> = liveData {
        var i = 1
        while (true) {
            emit("${i++}")
            delay(1000)
        }
    }
    val data: LiveData<String> = _data
    private val _generateList = liveData<List<String>> {
        var i = 1
        val result = mutableListOf<String>()
        while (i < 100) {
            result.add("无配置带ViewModel的Activity[$i]")
            i++
        }
        emit(result)
    }
    val generateList: LiveData<List<String>> = _generateList

    // Exposed LiveData from a function that returns a LiveData generated with a liveData builder
    private val currentTime = liveData<Long> {
        while (true) {
            emit(System.currentTimeMillis())
            delay(1000)
        }
    }

    // Coroutines inside a transformation
    val currentTimeTransformed = currentTime.switchMap {
        // timeStampToTime is a suspend function so we need to call it from a coroutine.
        liveData { emit(timeStampToTime(it)) }
    }

    // Simulates a long-running computation in a background thread
    private suspend fun timeStampToTime(timestamp: Long): String {
        delay(500)  // Simulate long operation
        val date = Date(timestamp)
        return date.toString()
    }


}